<!-- 参数收起组件，弹窗 + 表格 + json数据展示 -->

<template>
  <div style="width: 100%" @click="openDialogTable">
    <el-input
      v-model="mvalue"
      v-bind="mergeInputProps"
      clearable
      readonly
      :disabled="disabled"
    >
      <template #suffix>
        <el-icon @click.stop="handleClear" v-if="mvalue" style="cursor: pointer"
          ><CircleCloseFilled
        /></el-icon>
        <el-icon v-else><ArrowDown /></el-icon>
      </template>
    </el-input>
    <basic-dialog
      :title="mergeComProps.title"
      v-model="visible"
      :width="mergeComProps.width"
      :autoClose="false"
      @submit="handleSubmit"
    >
      <div style="display: flex">
        <avue-crud
          style="flex: 1"
          v-bind="mergeCrudProps"
          :data="tableData"
          @row-save="handleSave"
          @row-update="handleEdit"
          @row-del="handleDel"
        ></avue-crud>
        <div style="margin-left: 6px">
          <h4>手动输入JSON参数，请保持json格式</h4>
          <el-input
            style="width: 300px"
            type="textarea"
            :rows="10"
            :autosize="{ minRows: 10 }"
            v-model="jsonValue"
            @blur="handleInputBlur"
          ></el-input>
        </div>
      </div>
    </basic-dialog>
  </div>
</template>

<script setup>
import { ElMessage } from 'element-plus'
import { merge } from 'lodash'
import { ref, watch } from 'vue'
const that = getCurrentInstance()
const props = defineProps({
  // 输入框参数
  inputProps: {
    type: Object,
    disabled: false,
    default: () => ({}),
  },
  // crud组件参数
  crudProps: {
    type: Object,
    default: () => ({}),
  },
  // 本组件参数
  comProps: {
    type: Object,
    default: () => ({}),
  },
  disabled: Boolean,
  label: String,
  // 类型：add：新增 edit: 编辑 为空则为查询
  boxType: String,
})
const mvalue = defineModel()
const defaultCrudProps = {
  option: {
    height: '40vh',
    searchSpan: 8,
    menuWidth: 180,
    selection: false,
    column: [
      {
        label: '参数名称',
        prop: 'label',
        width: 200,
        sortable: true,
        rules: [
          { required: true, message: '参数名称不能为空', trigger: 'blur' },
        ],
      },
      {
        label: '参数的值',
        prop: 'value',
        sortable: true,
        rules: [
          { required: true, message: '参数的值不能为空', trigger: 'blur' },
        ],
      },
    ],
  },
}
const defaultInputProps = {
  placeholder: (!props.boxType ? '请输入 ' : '请选择 ') + props.label,
}
const defaultComProps = {
  showField: 'params',
  title: '参数收集',
  width: '1000',
}
// 合并默认值与props值
const mergeCrudProps = computed(() =>
  merge({}, defaultCrudProps, props.crudProps)
)
const mergeInputProps = computed(() =>
  merge({}, defaultInputProps, props.inputProps)
)
const mergeComProps = computed(() => merge({}, defaultComProps, props.comProps))

const visible = ref(false)
const jsonValue = ref('{}')
// 表单数据
const tableData = ref([])
const openDialogTable = () => {
  if (mvalue.value) {
    tableData.value = structureConvert(JSON.parse(mvalue.value), 'table')
  } else {
    tableData.value = []
  }
  visible.value = true
}

// 结构转换
// type: object 转为对象 table：转为表格
const structureConvert = (data, type) => {
  if (type === 'object') {
    let obj = {}
    data.forEach((item) => {
      obj[item.label] = obj[item.value]
    })
    return obj
  } else if (type === 'table') {
    let list = []
    const keys = Object.keys(data)
    keys.forEach((item) => {
      list.push({ label: item, value: data[item] })
    })
    return list
  }
}
// 输入框失去焦点事件，JSON转表格
const handleInputBlur = () => {
  try {
    const obj = JSON.parse(jsonValue.value)
    if (typeof obj === 'object') {
      tableData.value = Object.keys(obj).map((key) => ({
        label: key,
        value: obj[key],
      }))
    }
  } catch (error) {
    ElMessage.error('JSON格式错误：' + error.message)
  }
}
watch(
  () => tableData.value,
  (newVal) => {
    let obj = {}
    newVal.forEach((item) => {
      obj[item.label] = item.value
    })
    jsonValue.value = JSON.stringify(obj, null, 2)
  },
  { deep: true }
)

// 获取basicCrud组件实例的formData
const getbaiscCrudFormData = (instace = that) => {
  if (instace?.parent?.type.__name === 'BasicCrud') {
    return instace.parent.setupState
  } else {
    return instace.parent && getbaiscCrudFormData(instace.parent)
  }
}

const handleSave = (row, done, loading) => {
  tableData.value.push(row)
  done()
  loading()
}
const handleEdit = (row, index, done, loading) => {
  tableData.value.splice(index, 1, row)
  done()
  loading()
}

const handleDel = (row, index) => {
  tableData.value.splice(index, 1)
}

const handleSubmit = () => {
  try {
    if (JSON.parse(jsonValue.value)) {
      mvalue.value = jsonValue.value
      visible.value = false
    }
  } catch (error) {
    ElMessage.error('JSON格式错误：' + error.message)
  }
}

const handleClear = () => {
  tableData.value = []
  jsonValue.value = ''
  mvalue.value = jsonValue.value
}
</script>

<style lang="scss" scoped></style>
